/*
 * Copyright 2009 BioTeam Inc
 * 
 * Licensed under License GNU LESSER GENERAL PUBLIC LICENSE version 3.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.bioteam.appweb.gwt.apps.server;

import java.io.File;
import java.security.MessageDigest;
import java.util.Map;

import javax.mail.MessagingException;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.servlet.http.HttpSession;

import net.bioteam.appweb.Config;
import net.bioteam.appweb.gwt.apps.clientandserver.LoginProxy;
import net.bioteam.common.user.User;
import net.bioteam.common.user.UserInfo;
import net.bioteam.common.user.Users;
import net.bioteam.common.utils.MailSender;
import net.bioteam.common.utils.MyEntityManager;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class LoginServlet extends RemoteServiceServlet implements LoginProxy
{

	private static final long serialVersionUID = 1L;
	public static final Log logger = LogFactory.getLog(LoginServlet.class);

	public User login(Map<String, String> userInfo) throws Exception
	{
		String username = userInfo.get("username");
		String password = userInfo.get("password");
		if (username == null)
		{
			throw new Exception("username is emtpy");

		} else if (password == null)
		{
			throw new Exception("password is empty");
		} else
		{
			User user = Users.getUser(username);
			if (user == null)
			{
				throw new Exception("user " + StringEscapeUtils.escapeHtml(username) + " does not exist");
			}
			if (!user.isActive())
			{
				throw new Exception("user " + StringEscapeUtils.escapeHtml(username) + " does not exist.");
			}
			MessageDigest md = MessageDigest.getInstance("MD5");
			String serverhash = new String(Hex.encodeHex(md.digest(new String(user.getPassword() + "_" + username).getBytes())));		
			if (!serverhash.equals(password))
			//if (!user.getPassword().equals(password))
			{	
				throw new Exception("Wrong username or password");
			}
			getThreadLocalRequest().getSession(true).setAttribute("username", username);
			getThreadLocalRequest().getSession(true).setAttribute("user", user);

			initUser(username);
			User tempuser = new User();
			tempuser.setName(user.getName());
			tempuser.setRole(user.getRole());
			tempuser.setPassword("appnode_3_" + Config.DEFAULT_PROGRAM);

			return tempuser;
		}
	}

	public String register(Map<String, String> userInfo) throws Exception
	{
		String username = userInfo.get("username");
		String password = userInfo.get("password");
		String email = userInfo.get("email");
		String hash = userInfo.get("hash");
		if (username == null)
		{
			throw new Exception("username is emtpy");

		} else if (password == null)
		{
			throw new Exception("password is empty");
		} else if (email == null)
		{
			throw new Exception("email is empty");
		} else if (hash == null)
		{
			throw new Exception("unknow server error: potential robot attack");
		}
		MessageDigest md = MessageDigest.getInstance("MD5");

		String serverhash = new String(Hex.encodeHex(md.digest(new String(email + "_" + username).getBytes())));
		if (!hash.equals(serverhash))
		{
			throw new Exception("unknow server error: potential robot attack");
		}
		User user = Users.getUser(username);
		if (user != null)
		{
			throw new Exception("Please choose a different username");
		}
		user = Users.getUserByEmail(email);
		if (user != null)
		{
			throw new Exception("User with the email address already exist. Please choose a different email or retrieve your username/password by email.");
		}
		user = new User();
		user.setName(username);
		user.setPassword(password);
		user.setEmail(email);
		user.setRole("user");
		UserInfo info = new UserInfo();
		info.setDailyquote(Config.DEFAULT_DAILYQUOTE);
		user.setUserInfo(info);
		if (Config.DEFAULT_ACTIVEUSER)
		{
			user.setActive(true);
		}
		EntityManager em = MyEntityManager.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		try
		{
			tx.begin();
			em.persist(user);
			tx.commit();
		} catch (Exception e)
		{
			throw new Exception(" Server Error: " + e.getMessage());
		}
		if (MailSender.session == null)
		{
			throw new Exception(" Server Error: can not send email");
		}
		if (MailSender.session != null)
		{
			MailSender sender = new MailSender();
			try
			{
				sender.openTransport();
				StringBuffer sb = new StringBuffer();
				sb.append("Your User Name: " + user.getName() + "\n");
				sb.append("Your access password: " + user.getPassword() + "\n");
				sender.sendMessag(Config.ADMIN_EMAIL, user.getEmail(), sb.toString(), "Your inquiry account information");
			} catch (MessagingException e)
			{
				logger.warn(e.getMessage());
				throw new Exception(" Server Error: can not send email " + e.getMessage());
			}
		}
		return "";
	}

	public String logout() throws Exception
	{
		HttpSession session = getThreadLocalRequest().getSession(false);
		if (session != null)
		{
			session.invalidate();
		}
		return "";
	}

	public static void initUser(String username) throws Exception
	{
		File tempFile = new File(Config.USER_FILE + File.separator + username);
		if (!tempFile.exists())
		{
			tempFile.mkdirs();
		}
		tempFile = new File(Config.topWorkdir + File.separator + username);
		if (!tempFile.exists())
		{
			tempFile.mkdirs();
		}
	}

	public String retrieve(String email, String hash) throws Exception
	{
		if (email == null)
		{
			throw new Exception("email is empty");
		}
		if (hash == null)
		{
			throw new Exception("unknow server error: potential robot attack");
		}
		MessageDigest md = MessageDigest.getInstance("MD5");

		String serverhash = new String(Hex.encodeHex(md.digest(new String(email + "_bin").getBytes())));
		if (!hash.equals(serverhash))
		{
			throw new Exception("unknow server error: potential robot attack");
		}
		User user = Users.getUserByEmail(email);
		if (user == null)
		{
			throw new Exception(" No account is associated with this email");
		}
		if (MailSender.session == null)
		{
			throw new Exception(" Server Error: can not send email");
		}
		if (MailSender.session != null)
		{
			MailSender sender = new MailSender();
			try
			{
				sender.openTransport();
				StringBuffer sb = new StringBuffer();
				sb.append("Your User Name: " + user.getName() + "\n");
				sb.append("Your access password: " + user.getPassword() + "\n");

				sender.sendMessag(Config.ADMIN_EMAIL, user.getEmail(), sb.toString(), "Your inquiry account information");
			} catch (MessagingException e)
			{
				logger.warn(e.getMessage());
				throw new Exception(" Server Error: can not send email " + e.getMessage());
			}
		}
		return "";

	}
}
